#include "String.h"
#include <assert.h>

namespace bit
{
    string::string(const char* str)
    {
        int len = strlen(str);
        _str = new char[len + 2];//多开两个字符，方便不越界
        _size = len;
        _capacity = len;
        strcpy(_str,str);
    }

    string::string(const string& s)
    {
        // _str = new char[s._capacity + 2];
        // _size = s._size;
        // _capacity = s._capacity;
        // strcpy(_str,s._str);

        string tmp(s._str);//为什么会不行呢？？？？？
        swap(tmp);
    }

    string& string:: operator=(string s)
    {
        swap(s);
        return *this;
    }

    void string::push_back(char c)
    {
        *this += c;
    }

    string& string::operator+=(char c)
    {
        if(_size == _capacity)
        {
            int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
            reserve(newcapacity);
        }
        _str[_size] = c;
        _size++;
        _str[_size] = '\0';
        return* this;
    }

    void string::append(const char* str)
    {
        int len = strlen(str);
        if(_size == _capacity || ((_size + len) > _capacity))
        {
            int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
            reserve(newcapacity);
        }
        strcpy(_str + _size, str);
        _size += len;
        _str[_size] = '\0';
    }

    void string::operator+=(const char* str)
    {
        append(str);
    }

    void string::clear()
    {
        _str[0] = '\0';
        _size = 0;
    }

    void string::swap(string& s)
    {
        std::swap(_str,s._str);
        std::swap(_size,s._size);
        std::swap(_capacity,s._capacity);
    }

    void string::resize(size_t n, char c)
    {
        if(n > _capacity)
        {
            reserve(n);
            for(int i = _size;i <= _capacity; i++)
            {
                _str[i] = c;
                cout << i-_size << endl;
            }
            _str[_capacity] = '\0';
            _size = _capacity;
        }
    }

    void string::reserve(size_t n)
    {
        if(n > _capacity)
        {
            char* temp = new char[n + 2];
            strcpy(temp,_str);
            delete[] _str;
            _str = temp;
            _capacity = n;
        }
    }

    bool string::operator<(const string& s)
    {
        return strcmp(_str,s._str) < 0;
    }

    bool string::operator<=(const string& s)
    {
        return *this < s || *this == s;
    }

    bool string::operator>(const string& s)
    {
        return strcmp(_str,s._str) > 0;
    }

    bool string::operator>=(const string& s)
    {
        return *this > s || *this == s;
    }

    bool string::operator==(const string& s)
    {
        return strcmp(_str,s._str) == 0;
    }

    bool string::operator!=(const string& s)
    {
        return !(*this == s);
    }

    // 返回c在string中第一次出现的位置
    size_t string::find (char c, size_t pos) const
    {
        for(int i = pos; i < _size; i++)
        {
            if(_str[i] == c)
            {
                return i;
            }
        }
        return npos;
    }
    // 返回子串s在string中第一次出现的位置
    size_t string::find (const char* s, size_t pos) const
    {
        char* temp = strstr(_str + pos,s);
        if(temp == NULL)
        {
            return npos;
        }
        return temp - _str;
    }
    // 在pos位置上插入字符c/字符串str，并返回该字符的位置
    string& string::insert(size_t pos, char c)
    {
        assert(pos <= _size);
        if(_size == _capacity || _size + 1 > _capacity)
        {
            int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
            reserve(newcapacity);
        }
        int end = _size;
        while(end >= (int)pos)
        {
            _str[end + 1] = _str[end];
            end--;
        }
        _str[pos] = c;
        _size++;
        return *this;
    }

    string& string::insert(size_t pos, const char* str)
    {
        assert(pos <= _size);
        int len = strlen(str);
        if(_size == _capacity || _size + len > _capacity)
        {
            int newcapacity = _capacity == 0 ? 4 : _capacity * 2;
            reserve(newcapacity);
        }

        int end = _size;
        while(end >= (int)pos)
        {
            _str[end + len] = _str[end];
            end--;
        }
        strncpy(_str + pos,str,len);

        _size += len;
        return *this;
    }
    // 删除pos位置上的元素，并返回该元素的下一个位置
    string& string::erase(size_t pos, size_t len)
    {
        assert(pos < _size);
        if(len == npos || pos + len >= _size)
        {
            _str[pos] = '\0';
            _size = pos;
        }
        else
        {
            int tail = pos;
            memcpy(_str+pos,_str+pos+len,_size - pos - len);
            _size -= len;
            _str[_size] = '\0';//懒得计算，反正写上绝对不会出错
        }
        return *this;
    }

    ostream& operator<<(ostream& _cout, const bit::string& s)
    {
        _cout << s.c_str();
        return _cout;
    }
    
    istream& operator>>(istream& _cin, bit::string& s)
    {
        s.clear();
        char ch = _cin.get();
        while(ch != '\n')
        {
            s += ch;
            ch = _cin.get();
        }
        return _cin;
    }

    // void test()
    // {
    //     string s1("c");
    //     string s2("b");
    //     bool ret = s1 > s2;
    //     cout << ret << endl;
    // }

    void test()
    {
        string s1("hello world");
        string s2(s1);
        cout << s2 << endl;
        string s3 = "bit";
        s1 = s3;
        cout << s1 << endl;
        // string s1;
        // cin >> s1;
        // cout << s1 << endl;
        // string s1("hello world");
        // cout << s1 <<endl;
        // s1.erase(4,3);
        // cout << s1 <<endl;
        // cout << s1.size() <<endl;
        // string s1("hello world");
        // s1.insert(0,'x');
        // cout << s1 << endl;
        // s1.insert(s1.size()," HELLO WORLD ");
        // cout << s1 << endl;
        // string s1("hello world");
        // s1.insert(s1.find('d'),'s');
        // for(int i = '0';i <= '9';i++)
        // {
        //     cout << s1 << endl;
        //     cout << s1.size() <<endl;
        //     cout << s1.capacity() <<endl;
        //     s1.insert(s1.size(),i);
        // }
        // s1.insert(s1.find('d'),'s');
        // s1.insert(s1.find('d'),'s');
        // s1.insert(s1.find('d'),'s');
        // s1.insert(s1.find('d'),'s');
        // s1.insert(s1.find('d'),'s');
        // s1.insert(s1.find('d'),'s');
        // s1.insert(s1.find('d'),'s');
        // cout << s1 << endl;
        // cout << s1.size() <<endl;
        // cout << s1.capacity() <<endl;
        // string s2("hello bit");
        // s1 = s2;
        // cout << s1 << endl;
        // string s1("hello world");
        // string s2(s1);
        // cout << s2 << endl;
        // string s1("hello world");
        // int i = s1.find("world",0);
        // cout << i <<endl;
    }

    // void test()
    // {
    // //    string s1("hello world");
    // //    int i = s1.find('d');
    // //    cout << i << endl;
    //     // string s1("hello world");
    //     // s1.push_back('b');
    //     // s1.push_back('i');
    //     // s1.push_back('t');
    //     // cout << s1 << endl;
    //     // std::string s1("hello world");
    //     // cout << s1 <<endl;
    //     // cout << s1.size() <<endl;
    //     // cout <<s1.capacity() <<endl;
    //     // s1.clear();
    //     // cout << s1 <<endl;
    //     // cout << s1.size() <<endl;
    //     // cout <<s1.capacity() <<endl;
    // }

    // void test()
    // {
    //     // string s1;
    //     // cin >> s1;
    //     // cout << s1 << endl;
    //     // string s1("hello");
    //     // cout << s1 << endl;
    //     // cout << s1.size() <<endl;
    //     // cout << s1.capacity() <<endl;
    //     // s1.append(" world");
    //     // cout << s1 << endl;
    //     // cout << s1.size() <<endl;
    //     // cout << s1.capacity() <<endl;
    //     // s1.append(" bit");
    //     // cout << s1 << endl;
    //     // cout << s1.size() <<endl;
    //     // cout << s1.capacity() <<endl;
    //     // s1.append(" lllll");
    //     // cout << s1 << endl;
    //     // cout << s1.size() <<endl;
    //     // cout << s1.capacity() <<endl;
    //     // std::string s1("hello world");
    //     // cout << s1 << endl;
    //     // s1.append("sssssss");
    //     // cout << s1 << endl;
    //     // string s1("hello world");
    //     // cout << s1 << endl;
    //     // s1+='x';
    //     // cout << s1 << endl;
    //     // s1+='s';
    //     // s1+='x';
    //     // cout << s1 << endl;
    //     // cout << 'x' << endl;
    //     // string s1("hello world");
    //     // s1.resize(500,'b');
    //     // cout << s1 << endl;
    //     // cout << s1.size() << endl;
    //     // cout << s1.capacity() << endl;
    //     // cout << s1 <<endl;
    //     // cout << s1.capacity() <<endl;
    //     // cout << s1.size() <<endl;

    //     // s1.reserve(500);
    //     // cout << s1 <<endl;
    //     // cout << s1.capacity() <<endl;
    //     // cout << s1.size() <<endl;

    //     // string s1("hello world");
    //     // string s2("abcdsiajkasjkd");
    //     // s1.swap(s2);
    //     // cout << s1 << endl;
    //     // cout << s2 << endl;
    //     // const string s1("hello world");
    //     // for(auto& e: s1)
    //     // {
    //     //     cout << e << ' ';
    //     // }
    //     // cout << endl;
    //     // string s2;
    //     // cout << s1.c_str() << endl;
    //     // cout << s2.c_str() << endl;
    // }
}

